home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-gobject / gtk-2.0 / gobject / propertyhelper.py < prev   
Encoding:
Python Source  |  2009-06-15  |  9.4 KB  |  298 lines

  1. # -*- Mode: Python; py-indent-offset: 4 -*-
  2. # pygobject - Python bindings for the GObject library
  3. # Copyright (C) 2007 Johan Dahlin
  4. #
  5. #   gobject/propertyhelper.py: GObject property wrapper/helper
  6. #
  7. # This library is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU Lesser General Public
  9. # License as published by the Free Software Foundation; either
  10. # version 2.1 of the License, or (at your option) any later version.
  11. #
  12. # This library is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. # Lesser General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public
  18. # License along with this library; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  20. # USA
  21.  
  22. import sys
  23.  
  24. import gobject._gobject
  25. _gobject = sys.modules['gobject._gobject']
  26.  
  27. from gobject.constants import \
  28.      TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, \
  29.      TYPE_BOOLEAN, TYPE_INT, TYPE_UINT, TYPE_LONG, \
  30.      TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM, \
  31.      TYPE_FLAGS, TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, \
  32.      TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
  33.      TYPE_PYOBJECT
  34. from gobject.constants import \
  35.      G_MINFLOAT, G_MAXFLOAT, G_MINDOUBLE, G_MAXDOUBLE, \
  36.      G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, \
  37.      G_MAXULONG
  38.  
  39.  
  40. class property(object):
  41.     """
  42.     Creates a new property which in conjunction with GObject subclass will
  43.     create a property proxy:
  44.  
  45.     >>> class MyObject(gobject.GObject):
  46.     >>> ... prop = gobject.property(type=str)
  47.  
  48.     >>> obj = MyObject()
  49.     >>> obj.prop = 'value'
  50.  
  51.     >>> obj.prop
  52.     'value'
  53.  
  54.     The API is similar to the builtin property:
  55.  
  56.     class AnotherObject(gobject.GObject):
  57.         @gobject.property
  58.         def prop(self):
  59.             return ...
  60.  
  61.     Which will create a read-only property called prop.
  62.     """
  63.  
  64.     class __metaclass__(type):
  65.         def __repr__(self):
  66.             return "<class 'gobject.property'>"
  67.  
  68.     def __init__(self, getter=None, setter=None, type=None, default=None,
  69.                  nick='', blurb='', flags=_gobject.PARAM_READWRITE,
  70.                  minimum=None, maximum=None):
  71.         """
  72.         @param  getter: getter to get the value of the property
  73.         @type   getter: callable
  74.         @param  setter: setter to set the value of the property
  75.         @type   setter: callable
  76.         @param    type: type of property
  77.         @type     type: type
  78.         @param default: default value
  79.         @param    nick: short description
  80.         @type     bick: string
  81.         @param   blurb: long description
  82.         @type    blurb: string
  83.         @param flags:    parameter flags, one of:
  84.         - gobject.PARAM_READABLE
  85.         - gobject.PARAM_READWRITE
  86.         - gobject.PARAM_WRITABLE
  87.         - gobject.PARAM_CONSTRUCT
  88.         - gobject.PARAM_CONSTRUCT_ONLY
  89.         - gobject.PARAM_LAX_VALIDATION
  90.         @keyword minimum:  minimum allowed value (int, float, long only)
  91.         @keyword maximum:  maximum allowed value (int, float, long only)
  92.         """
  93.  
  94.         if getter and not setter:
  95.             setter = self._readonly_setter
  96.         elif setter and not getter:
  97.             getter = self._writeonly_getter
  98.         elif not setter and not getter:
  99.             getter = self._default_getter
  100.             setter = self._default_setter
  101.         self.getter = getter
  102.         self.setter = setter
  103.  
  104.         if type is None:
  105.             type = object
  106.         self.type = self._type_from_python(type)
  107.         self.default = self._get_default(default)
  108.         self._check_default()
  109.  
  110.         if not isinstance(nick, basestring):
  111.             raise TypeError("nick must be a string")
  112.         self.nick = nick
  113.  
  114.         if not isinstance(blurb, basestring):
  115.             raise TypeError("blurb must be a string")
  116.         self.blurb = blurb
  117.  
  118.         if flags < 0 or flags > 32:
  119.             raise TypeError("invalid flag value: %r" % (flags,))
  120.         self.flags = flags
  121.  
  122.         if minimum is not None:
  123.             if minimum < self._get_minimum():
  124.                 raise TypeError(
  125.                     "Minimum for type %s cannot be lower than %d" % (
  126.                     self.type, self._get_minimum()))
  127.         else:
  128.             minimum = self._get_minimum()
  129.         self.minimum = minimum
  130.         if maximum is not None:
  131.             if maximum > self._get_maximum():
  132.                 raise TypeError(
  133.                     "Maximum for type %s cannot be higher than %d" % (
  134.                     self.type, self._get_maximum()))
  135.         else:
  136.             maximum = self._get_maximum()
  137.         self.maximum = maximum
  138.  
  139.         self.name = None
  140.  
  141.         self._values = {}
  142.         self._exc = None
  143.  
  144.     def __repr__(self):
  145.         return '<gobject property %s (%s)>' % (
  146.             self.name or '(uninitialized)',
  147.             _gobject.type_name(self.type))
  148.  
  149.     def __get__(self, instance, klass):
  150.         if instance is None:
  151.             return self
  152.  
  153.         self._exc = None
  154.         value = instance.get_property(self.name)
  155.         if self._exc:
  156.             exc = self._exc
  157.             self._exc = None
  158.             raise exc
  159.  
  160.         return value
  161.  
  162.     def __set__(self, instance, value):
  163.         if instance is None:
  164.             raise TypeError
  165.  
  166.         self._exc = None
  167.         instance.set_property(self.name, value)
  168.         if self._exc:
  169.             exc = self._exc
  170.             self._exc = None
  171.             raise exc
  172.  
  173.     def _type_from_python(self, type):
  174.         if type == int:
  175.             return TYPE_INT
  176.         elif type == bool:
  177.             return TYPE_BOOLEAN
  178.         elif type == long:
  179.             return TYPE_LONG
  180.         elif type == float:
  181.             return TYPE_DOUBLE
  182.         elif type == str:
  183.             return TYPE_STRING
  184.         elif type == object:
  185.             return TYPE_PYOBJECT
  186.         elif type == _gobject.GObject:
  187.             return TYPE_OBJECT
  188.         elif type in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
  189.                       TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
  190.                       TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM,
  191.                       TYPE_FLAGS, TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
  192.                       TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
  193.                       TYPE_PYOBJECT]:
  194.             return type
  195.         else:
  196.             raise TypeError("Unsupported type: %r" % (type,))
  197.  
  198.     def _get_default(self, default):
  199.         ptype = self.type
  200.         if default is not None:
  201.             return default
  202.  
  203.         if ptype in [TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
  204.                      TYPE_INT64, TYPE_UINT64]:
  205.             return 0
  206.         elif ptype == TYPE_STRING:
  207.             return ''
  208.         elif ptype == TYPE_FLOAT or ptype == TYPE_DOUBLE:
  209.             return 0.0
  210.         else:
  211.             return None
  212.  
  213.     def _check_default(self):
  214.         ptype = self.type
  215.         default = self.default
  216.         if (ptype == TYPE_BOOLEAN and (default not in (True, False))):
  217.             raise TypeError(
  218.                 "default must be True or False, not %r" % (default,))
  219.         elif ptype == TYPE_PYOBJECT:
  220.             if default is not None:
  221.                 raise TypeError("object types does not have default values")
  222.  
  223.     def _get_minimum(self):
  224.         ptype = self.type
  225.         if ptype in [TYPE_UINT, TYPE_ULONG, TYPE_UINT64]:
  226.             return 0
  227.         elif ptype == TYPE_FLOAT:
  228.             return G_MINFLOAT
  229.         elif ptype == TYPE_DOUBLE:
  230.             return G_MINDOUBLE
  231.         elif ptype == TYPE_INT:
  232.             return G_MININT
  233.         elif ptype == TYPE_LONG:
  234.             return G_MINLONG
  235.         elif ptype == TYPE_INT64:
  236.             return -2 ** 62 - 1
  237.  
  238.         return None
  239.  
  240.     def _get_maximum(self):
  241.         ptype = self.type
  242.         if ptype == TYPE_UINT:
  243.             return G_MAXUINT
  244.         elif ptype == TYPE_ULONG:
  245.             return G_MAXULONG
  246.         elif ptype == TYPE_INT64:
  247.             return 2 ** 62 - 1
  248.         elif ptype == TYPE_UINT64:
  249.             return 2 ** 63 - 1
  250.         elif ptype == TYPE_FLOAT:
  251.             return G_MAXFLOAT
  252.         elif ptype == TYPE_DOUBLE:
  253.             return G_MAXDOUBLE
  254.         elif ptype == TYPE_INT:
  255.             return G_MAXINT
  256.         elif ptype == TYPE_LONG:
  257.             return G_MAXLONG
  258.  
  259.         return None
  260.  
  261.     #
  262.     # Getter and Setter
  263.     #
  264.  
  265.     def _default_setter(self, instance, value):
  266.         self._values[instance] = value
  267.  
  268.     def _default_getter(self, instance):
  269.         return self._values.get(instance, self.default)
  270.  
  271.     def _readonly_setter(self, instance, value):
  272.         self._exc = TypeError("%s property of %s is read-only" % (
  273.             self.name, type(instance).__name__))
  274.  
  275.     def _writeonly_getter(self, instance):
  276.         self._exc = TypeError("%s property of %s is write-only" % (
  277.             self.name, type(instance).__name__))
  278.  
  279.     #
  280.     # Public API
  281.     #
  282.  
  283.     def get_pspec_args(self):
  284.         ptype = self.type
  285.         if ptype in [TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
  286.                      TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE]:
  287.             args = self._get_minimum(), self._get_maximum(), self.default
  288.         elif ptype == TYPE_STRING or ptype == TYPE_BOOLEAN:
  289.             args = (self.default,)
  290.         elif ptype == TYPE_PYOBJECT:
  291.             args = ()
  292.         elif ptype == TYPE_OBJECT:
  293.             args = ()
  294.         else:
  295.             raise NotImplementedError(ptype)
  296.  
  297.         return (self.type, self.nick, self.blurb) + args + (self.flags,)
  298.